package com.slunk.platforms;

import com.badlogic.gdx.utils.Array;

public class SActorsManager implements SActingObjectEvents {
	private Array<SActingObject> unobservedActors;
	private Array<SActingObject> observedActors;
	private Array<SActingObject> retiredActors;
	private SActorsManagerEvents eventHandler;
	private boolean activatedRandomState = false;
	
	/**
	 * creates new instances where it needs to.
	 */
	public SActorsManager() {
		unobservedActors = new Array<SActingObject>();
		observedActors = new Array<SActingObject>();
		retiredActors = new Array<SActingObject>();
		eventHandler = null;
	}

	public void setEventHandler(SActorsManagerEvents eventHandler) {
		this.eventHandler = eventHandler;
	}
	
	public SActorsManagerEvents getEventHandler() {
		return eventHandler;
	}
	
	public boolean enoughToAct() {
		if (countObserved() > 3 || countUnobserved() == 0) {
			return true;
		}
		return false;
	}
	
	public boolean hasActorsToAct() {
		if (observedActors.size > 0) {
			return true;
		}
		return false;
	}
	
	public int countUnobserved () {
		return unobservedActors.size;
	}
	
	public int countObserved() {
		return observedActors.size;
	}
	public int countRetired() {
		return retiredActors.size;
	}
	
	/**
	 * Hires actor and places into the unobserved pool
	 * @param actor
	 */
	public void hireActor(SActingObject actor) {
		//unobservedActors.add(actor);
		if (!unobservedActors.contains(actor, true)){
			unobservedActors.add(actor);
		}
	}
	
	/**
	 * Fires actor and removes (if exists) from the unobserved or observed pool
	 * @param actor
	 */
	public void fireActor(SActingObject actor) {
		if (unobservedActors.contains(actor, true)) {
			unobservedActors.removeValue(actor,true);
		} else if (observedActors.contains(actor, true)) {
			observedActors.removeValue(actor, true);
		}
	}
	
	/**
	 * Puts the actor in the observed pool and removes from unobserved pool if it exists there
	 * @param actor
	 */
	public void actorNoticed(SActingObject actor) {
		//System.out.println("actorNoticed");
		//remove from the unobserved pool
		if (unobservedActors.contains(actor, true)) {
			//System.out.println("Needs to be removed from unobserved pool");
			unobservedActors.removeValue(actor, true);
		//}
			//if has more states, then send to the observed actors pool
			if (actor.hasMoreStates() && !observedActors.contains(actor, true)) {
				//System.out.println("adding actor to the observed actors");
				observedActors.add(actor);
			} else {
				//System.out.println("retiring the actor");
				//else send to the retired pool
				retiredActors.add(actor);
			}
		} //else {
		//	System.out.println("already removed from unobserved pool");
		//}
	}
	
	/**
	 * Trigger a random state and remove from observed and add actor to unobserved pool
	 */
	public void randomNewStateFromObserved() {
		if (observedActors.size > 0) {
			activatedRandomState = true;
			
			SActingObject actor = observedActors.random();
			actor.activateNextState();
			
			//add to unobserved and remove from observed as it is a new state
			unobservedActors.add(actor);
			observedActors.removeValue(actor, true);
		}
	}

	@Override
	public void onChangedState(Object object) {
		// TODO Auto-generated method stub
		System.out.println("onChagnedState");
		if (activatedRandomState) {
			if (eventHandler != null) {
				eventHandler.onRandomStateActivated();
			}
			activatedRandomState = false;
		} else {
			if (eventHandler != null) {
				eventHandler.onStateActivated();
			}
		}
	}
}